package edu.scau.mis.pos.service.impl;

import edu.scau.mis.pos.entity.*;
import edu.scau.mis.pos.mapper.CategoryMapper;
import edu.scau.mis.pos.mapper.ItemMapper;
import edu.scau.mis.pos.mapper.OrderItemMapper;
import edu.scau.mis.pos.mapper.OrderMapper;
import edu.scau.mis.pos.service.IOrderItemService;
import edu.scau.mis.pos.vo.DashboardVo;
import edu.scau.mis.pos.vo.OrderItemVo;
import edu.scau.mis.pos.vo.PosResultVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.*;

/**
 * (PosOrderItem)表服务实现类
 *
 * @author makejava
 * @since 2021-11-10 17:15:45
 */
@Service("orderItemService")
public class IOrderItemServiceImpl implements IOrderItemService {
    Integer Q = null;
    Double A = null;
    Map<String,List<PosOrderItem>> mapCache = new HashMap<>(); //订单明细缓存数据
    Map<String, Object> orderCache = new HashMap<String,Object>(); //订单缓存数据
    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ItemMapper itemMapper;
    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private CategoryMapper categoryMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param orderItemId 主键
     * @return 实例对象
     */
    @Override
    public PosOrderItem queryById(Integer orderItemId) {
        return this.orderItemMapper.queryById(orderItemId);
    }

    /**
     * 分页查询
     *
     * @param posOrderItem 筛选条件
     * @return 查询结果
     */
    @Override
    public List<PosOrderItem> queryAll(PosOrderItem posOrderItem) { return this.orderItemMapper.queryAll(posOrderItem); }

    /**
     * 新增数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem insert(PosOrderItem posOrderItem) {
        this.orderItemMapper.insert(posOrderItem);
        return posOrderItem;
    }

    /**
     * 修改数据
     *
     * @param posOrderItem 实例对象
     * @return 实例对象
     */
    @Override
    public PosOrderItem update(PosOrderItem posOrderItem) {
        this.orderItemMapper.update(posOrderItem);
        return this.queryById(posOrderItem.getOrderItemId());
    }

    /**
     * 通过主键删除数据
     *
     * @param orderItemId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer orderItemId) {
        return this.orderItemMapper.deleteById(orderItemId) > 0;
    }


    /**
     * 步骤1：创建新订单
     * @return 订单信息
     */
    @Override
    public Map<String, Object> createOrder() {
        Timestamp time = new Timestamp(System.currentTimeMillis());//获取当前时间对象，"yyyy-MM-dd HH:mm:ss"
        String str = time.toString();                                //新订单创建时间
        Integer totalQuantity = 0;                                          //新订单商品总数初始值
        Double totalAmount = 0.00;                                            //新订单商品总价格初始值
        String year=str.substring(0,4);
        String month=str.substring(5,7);
        String day=str.substring(8,10);
        String hour=str.substring(11,13);
        String min=str.substring(14,16);
        String sed=str.substring(17,19);
        String newOrderNo = "so_" + year + month + day + "_" + hour + min + sed;          //新订单编号
        this.createMapCache(newOrderNo);  // 创建订单明细数据缓存
        orderCache.put("newOrderNo", newOrderNo);//添加新订单信息进缓存，分别使用，不再创建独立方法
        orderCache.put("saleDateTime", time);
        orderCache.put("totalAmount", totalAmount);
        orderCache.put("totalQuantity", totalQuantity);
        Map<String, Object> info = new HashMap<String,Object>();
        info.put("newOrderNo", newOrderNo);
        info.put("createOrderTime",str);
        return info;
    }


    /**
     * 生成缓存数据_内存存储_HashMap
     * 步骤1_依赖方法1
     * @param orderNo 订单编号
     * @return
     */
    private Map<String, List<PosOrderItem>> createMapCache(String orderNo){
        List<PosOrderItem> orderItemList = new ArrayList<>();
        mapCache.put(orderNo,orderItemList);
        return mapCache;
    }


    /**
     * 步骤2：添加商品到待购买列表
     * @param orderItemVo 传值对象
     * 封装了orderNo和itemNo和quantity
     * @return 待购商品列表
     */
    @Override
    public PosResultVo enterLineOrderItem(OrderItemVo orderItemVo) {
        //默认数量为1
        if(orderItemVo.getQuantity()==null){
            orderItemVo.setQuantity(1);
        }
        String nOrderNo = (String) orderCache.get("newOrderNo");
        PosItem posItem = this.itemMapper.queryItemByItemNo(orderItemVo.getItemNo());  //将要添加的商品的PosItem对象
        PosOrderItem posOrderItem = new PosOrderItem();                               //将要添加的商品的PosOrderItem对象
        posOrderItem.setOrderId(this.orderMapper.queryLastId().getOrderId()+1);
        posOrderItem.setItemId(posItem.getItemId());
        posOrderItem.setSalePrice(posItem.getPrice());
        posOrderItem.setQuantity(orderItemVo.getQuantity());
        //从mapCache中得到itemId，查询代购买商品集合，封装成getEnterItemListAndUpdateQuantity(orderNo，posOrderItem)
        return this.getEnterItemListAndUpdateQuantity(nOrderNo, posItem, posOrderItem);              //将商品加入缓存并更新缓存中商品数量
    }


    /**
     * 更新订单明细缓存，验证库存是否充足，将缓存中相同的商品合并，统计总金额和总数量
     * 步骤2_依赖方法1
     * @param orderNo 订单编号
     */
    private PosResultVo getEnterItemListAndUpdateQuantity(String orderNo, PosItem posItem, PosOrderItem posOrderItem){
        Map<String, Object> info = new HashMap<String,Object>();
        PosResultVo posResultVo = new PosResultVo();
        Integer Quantity;
        List<PosOrderItem> orderItemList = mapCache.get(orderNo);
        if(orderItemList.isEmpty() && posItem.getInventory()>=posOrderItem.getQuantity() && posOrderItem.getQuantity()>0){
            orderItemList.add(posOrderItem);
            posResultVo.setMessage("添加成功");
        }
        else if(orderItemList.isEmpty() && posItem.getInventory() < posOrderItem.getQuantity()){
            posResultVo.setMessage("库存不足");
        }
        else {
            for (int i =0; i<orderItemList.size(); i++) {
                PosOrderItem orderItem = orderItemList.get(i);
                if (Objects.equals(orderItem.getItemId(), posOrderItem.getItemId())) {  //判断是否有相同商品
                    Quantity = orderItem.getQuantity();    //将缓存中相同的商品的数量取出
                    //验证库存是否充足
                    if(posItem.getInventory()>=posOrderItem.getQuantity()+Quantity && posOrderItem.getQuantity()>0) {
                        orderItem.setQuantity(orderItem.getQuantity() + posOrderItem.getQuantity());     //合并相同订单
                        orderItemList.set(i, orderItem);
                        posResultVo.setMessage("添加成功");
                    }
                    else{
                        posResultVo.setMessage("库存不足");
                    }
                    break;
                }
                else if (i == orderItemList.size()-1 && !Objects.equals(orderItem.getItemId(), posOrderItem.getItemId())){
                    if(posItem.getInventory()>=posOrderItem.getQuantity()){
                        orderItemList.add(posOrderItem);
                        posResultVo.setMessage("添加成功");
                    }
                    else{
                        posResultVo.setMessage("库存不足");
                    }
                    break;
                }
            }
        }
        if (Objects.equals(posResultVo.getMessage(),"添加成功")){
            A = (Double) orderCache.get("totalAmount");
            A += posOrderItem.getQuantity()*posOrderItem.getSalePrice();  //统计代购买商品总金额
            Q = (Integer)orderCache.get("totalQuantity");
            Q += posOrderItem.getQuantity();                            //统计代购买商品总数
            orderCache.put("totalAmount",A);
            orderCache.put("totalQuantity",Q);                           //更新总金额及总数缓存
        }
        //更新订单明细缓存
        mapCache.put(orderNo,orderItemList);
        //将orderItemList变为enterItemList，获取item列表
        List<PosItem> enterItemList = new ArrayList<>();
        orderItemList = mapCache.get(orderNo);
        for(PosOrderItem orderItem : orderItemList){
            PosItem Item = this.itemMapper.queryById(orderItem.getItemId());
            Item.setQuantity(orderItem.getQuantity());
            enterItemList.add(Item);
        }
        info.put("itemList",enterItemList);
        posResultVo.setData(info);
        posResultVo.setTotalAmount(A);
        posResultVo.setTotalQuantity(Q);
        return posResultVo;
    }


    /**
     * 得到代购买商品总金额和总数量
     * @return 订单缓存
     */
    public Map<String, Object> getTotalQuantityAndTotalAmount(){
        return orderCache;
    }


    /**
     * 步骤3：确认购买
     */
    @Override
    public boolean ConfirmPurchaseItem() {
        PosOrder posOrder = new PosOrder();
        posOrder.setOrderNo((String)orderCache.get("newOrderNo"));
        posOrder.setSaleDatetime(new Timestamp(System.currentTimeMillis()));
        posOrder.setTotalAmount((Double) orderCache.get("totalAmount"));
        posOrder.setTotalQuantity((Integer) orderCache.get("totalQuantity"));
        boolean flag = false;
        int orderFlag = 0;
        int orderItemFlag = 0;
        List<PosOrderItem> orderItemList = mapCache.get(posOrder.getOrderNo());
        if(!orderItemList.isEmpty()) {
            orderFlag = this.orderMapper.insert(posOrder);
            orderItemFlag = this.orderItemMapper.insertBatch(orderItemList);
            updateItemInventory(orderItemList);
        }
        if(orderFlag > 0 && orderItemFlag > 0){
            flag = true;
            mapCache.clear();
            orderCache.clear();
        }
        return flag;
    }


    /**
     * 更新商品库存
     * 步骤3_依赖方法1
     * @param orderItemList 订单明细缓存数组
     */
    private void updateItemInventory(List<PosOrderItem> orderItemList){
        for (PosOrderItem orderItem : orderItemList) {
            PosItem posItem =  this.itemMapper.queryById(orderItem.getItemId());
            Integer i = posItem.getInventory();
            posItem.setInventory(i-orderItem.getQuantity());
            this.itemMapper.update(posItem);
        }
    }



    /**
     * 弃用
     * 删除缓存数据_内存存储_HashMap
     * 步骤3_依赖方法2
     * @param orderNo
     */
    private void removeMapCache(String orderNo) {
        Iterator<Map.Entry<String,List<PosOrderItem>>> iterator = mapCache.entrySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next().getKey();
            if (orderNo.equals(key)) {
                iterator.remove();
            }
        }
    }


    /**
     * 取消订单方法
     * @return 取消成功
     */
    @Override
    public String removeCache() {
        mapCache.clear();
        orderCache.clear();
        String str = "取消成功";
        return str;
    }


    /**
     * 按商品类别id统计购买数
     * @return 记录数
     */
    @Override
    public List<DashboardVo> CountByCategoryId(){
        List<PosCategory> categoryList = this.categoryMapper.queryAll(new PosCategory());
        List<DashboardVo> dashboardVoList = new ArrayList<>();
        for(PosCategory posCategory : categoryList){
            DashboardVo dashboardVo = new DashboardVo();
            long count = this.orderItemMapper.countByCategoryId(posCategory.getCategoryId());
            String name = posCategory.getCategoryName();
            dashboardVo.setValue(count);
            dashboardVo.setName(name);
            dashboardVoList.add(dashboardVo);
        }
        return dashboardVoList;
    }
}
